package cn.jbolt.core.service;

import cn.jbolt.core.Interceptor.JBoltSecurityCheck;
import cn.jbolt.core.base.JBoltMsg;
import cn.jbolt.core.base.config.JBoltConfig;
import cn.jbolt.core.cache.JBoltPermissionCache;
import cn.jbolt.core.cache.JBoltRoleCache;
import cn.jbolt.core.cache.JBoltUserCache;
import cn.jbolt.core.common.enums.JBoltSystemLogTargetType;
import cn.jbolt.core.kit.JBoltUserKit;
import cn.jbolt.core.model.Permission;
import cn.jbolt.core.model.Role;
import cn.jbolt.core.model.RolePermission;
import cn.jbolt.core.model.User;
import cn.jbolt.core.service.base.JBoltBaseService;
import cn.jbolt.core.util.JBoltArrayUtil;
import com.jfinal.kit.Okv;
import com.jfinal.kit.Ret;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 角色权限中间表Service
 *
 * @ClassName: RolePermissionService
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2019年11月9日
 */
public class JBoltRolePermissionService extends JBoltBaseService<RolePermission> {
	protected RolePermission dao = new RolePermission().dao();

	@Override
	protected RolePermission dao() {
		return dao;
	}

	/**
	 * 根据权限资源Key 反推拿到哪些角色拥有它
	 * @param permissionKey
	 * @return
	 */
	public List<Role> getRolesByPermissionKey(String permissionKey) {
		List<Long> ids = getRoleIdsByPermissionKey(permissionKey);
		if(notOk(ids)){
			return null;
		}
		List<Role> roles = new ArrayList<>();
		Role role;
		for(Long id:ids){
			role = JBoltRoleCache.me.get(id);
			if(role != null){
				roles.add(role);
			}
		}
		return roles;
	}

	/**
	 * 根据权限资源Key 反推拿到哪些角色拥有它
	 * @param permissionKey
	 * @return
	 */
	public List<Long> getRoleIdsByPermissionKey(String permissionKey) {
		if(notOk(permissionKey) || permissionKey.equals(JBoltPermissionService.PERMISSION_KEY_NONE)){
			return null;
		}
		//1、通过permissionKey获得Permission的id 从cache中
		Permission permission = JBoltPermissionCache.me.getByKey(permissionKey);
		if(permission == null){
			throw new RuntimeException("没有找到对应的权限定义["+permissionKey+"]");
		}
		return query(selectSql().select("role_id").eq("permission_id",permission.getId()));
	}

	/**
	 * 删除一个角色下的权限资源
	 *
	 * @param roleId
	 * @return
	 */
	public Ret deleteRolePermission(Long roleId) {
		if (notOk(roleId)) {
			return fail(JBoltMsg.PARAM_ERROR);
		}
		Ret ret = deleteBy(Okv.by("role_id", roleId));
		if (ret.isOk()) {
			// 删除缓存
			JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
		}
		return ret;
	}

	/**
	 * 处理角色变动资源
	 *
	 * @param roleId
	 * @param permissionStr
	 * @return
	 */
	public Ret doSubmit(Long roleId, String permissionStr) {
		if (JBoltConfig.DEMO_MODE) {
			return fail(JBoltMsg.DEMO_MODE_CAN_NOT_DELETE);
		}
		if (notOk(roleId) || notOk(permissionStr)) {
			return fail("参数有误");
		}
		Role role = JBoltRoleCache.me.get(roleId);
		if (role == null) {
			return fail("角色信息不存在");
		}
		String[] ids = JBoltArrayUtil.from(permissionStr, ",");
		if (ids.length == 0) {
			return fail("请选择分配的权限");
		}
		// 先删除以前的
		deleteRolePermission(roleId);
		// 添加现在的
		saveRolePermissions(roleId, ids);
		// 添加日志
		addUpdateSystemLog(roleId, JBoltUserKit.getUserId(),role.getName(),
				"的可用权限设置");
		return SUCCESS;
	}

	/**
	 * 保存一个角色分配的所有资源信息
	 *
	 * @param roleId
	 * @param ids
	 */
	private void saveRolePermissions(Long roleId, String[] ids) {
		List<RolePermission> permissions = new ArrayList<RolePermission>();
		RolePermission rolePermission = null;
		for (String id : ids) {
			rolePermission = new RolePermission();
			rolePermission.autoProcessIdValue();
			rolePermission.setRoleId(roleId);
			rolePermission.setPermissionId(Long.parseLong(id));
			permissions.add(rolePermission);
		}
		batchSave(permissions);
	}

	/**
	 * 获取指定多个角色的所有权限资源
	 *
	 * @param roleIds
	 * @return
	 */
	public Set<String> getPermissionsKeySetByRoles(String roleIds) {
		List<RolePermission> rolePermissions = getListByRoles(roleIds);
		if (rolePermissions == null || rolePermissions.size() == 0) {
			return null;
		}
		Set<String> set = new HashSet<String>();
		for (RolePermission rf : rolePermissions) {
			Permission f = JBoltPermissionCache.me.get(rf.getPermissionId());
			if (f != null) {
				set.add(f.getPermissionKey());
			}
		}
		return set;
	}
	/**
	 * 获取指定多个角色的所有权限资源
	 *
	 * @param roleIds
	 * @return
	 */
	public List<Permission> getPermissionsByRoles(String roleIds) {
		List<RolePermission> rolePermissions = getListByRoles(roleIds);
		if (rolePermissions == null || rolePermissions.size() == 0) {
			return null;
		}
		List<Permission> permissions = new ArrayList<Permission>();
		for (RolePermission rf : rolePermissions) {
			Permission f = JBoltPermissionCache.me.get(rf.getPermissionId());
			if (f != null) {
				permissions.add(f);
			}
		}
		return permissions;
	}

	/**
	 * 获取一个角色下的分配的权限资源数据
	 *
	 * @param roleId
	 * @return
	 */
	public List<RolePermission> getListByRole(Long roleId) {
		return getCommonList(Okv.by("role_id", roleId));
	}

	/**
	 * 获取多个角色下分配的权限资源数据
	 *
	 * @param roleIds
	 * @return
	 */
	public List<RolePermission> getListByRoles(String roleIds) {
		return find(selectSql().distinct("permission_id").in("role_id", roleIds).asc("permission_id"));
	}

	/**
	 * 检测一个角色是否包含指定的权限
	 *
	 * @param roleId
	 * @param permissionKey
	 * @return
	 */
	public boolean checkRoleHasPermission(Long roleId, String permissionKey) {
		Permission permission = JBoltPermissionCache.me.getByKey(permissionKey);
		if (permission == null) {
			return false;
		}
		RolePermission rolePermission = findFirst(Okv.by("role_id", roleId).set("permission_id", permission.getId()));
		return (rolePermission != null);
	}

	/**
	 * 检测一个用户是否包含指定的权限
	 *
	 * @param userId
	 * @param checkAll
	 * @param permissionKeys
	 * @return
	 */
	public boolean checkUserHasPermission(Long userId, boolean checkAll, String... permissionKeys) {
		if (permissionKeys == null || permissionKeys.length == 0) {
			return false;
		}
		User user = JBoltUserCache.me.get(userId);
		if (user == null) {
			return false;
		}
		// 是超管并且包含超管权限
		if (user.getIsSystemAdmin()) {
			boolean isSystemAdminPermission = JBoltSecurityCheck.checkIsSystemAdminDefaultPermission(checkAll,
					permissionKeys);
			if (isSystemAdminPermission) {
				return true;
			}
			// 如果是超管员 但是这个权限不是超管员专属的就再去普通校验把 如果是超管的就直接返回true了
		}
		// 超管权限校验后就开始校验角色分配权限了
		String roles = user.getRoles();
		if (notOk(roles)) {
			return false;
		}
		// 不是超管就直接check
		return JBoltSecurityCheck.checkHasPermission(checkAll, roles, permissionKeys);
	}

	/**
	 * 删除关联一个资源的所有role和资源的绑定数据
	 *
	 * @param permissionId
	 */
	public Ret deleteByPermission(Long permissionId) {
		return deleteBy(Okv.by("permission_id", permissionId));
	}

	/**
	 * 根据角色清空权限绑定
	 *
	 * @param roleId
	 * @return
	 */
	public Ret deleteByRole(Long roleId) {
		Ret ret = deleteRolePermission(roleId);
		if (ret.isOk()) {
			addUpdateSystemLog(roleId, JBoltUserKit.getUserId(),
					JBoltRoleCache.me.getName(roleId), "清空了角色绑定设置的所有权限资源");
		}
		return ret;
	}

	@Override
	protected int systemLogTargetType() {
		return JBoltSystemLogTargetType.ROLE.getValue();
	}

}
